.386
.model flat, stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\masm32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\masm32.lib
include \masm32\include\user32.inc 
includelib \masm32\lib\user32.lib

.data
filehandle DWORD ?;存储文件权柄

;提示指令
str1 BYTE "IMAGE_DOS_HEADER:",0
str2 BYTE "IMAGE_NT_HEADER:",0
str3 BYTE "IMAGE_FILE_HEADE:",0
str4 BYTE "IMAGE_OPTIONAL_HEADER:",0
str5 BYTE "    e_magic: ",0
str6 BYTE "    e_lfanew: ",0
str7 BYTE "    Signature: ",0
str8 BYTE "    NumberOfSections: ",0
str9 BYTE "    TimeDateStamp: ",0
stra BYTE "    Characteristic: ",0
strb BYTE "    AddressOfEntryPoint: ",0
strc BYTE "    ImageBase: ",0
strd BYTE "    SectionAligment: ",0
stre BYTE "    FileAligment: ",0
strf BYTE "Please input a PE file: ",0
path BYTE 4000 DUP(0);存储输入文件路径的字符串
endl BYTE 0ah,00h

filebuf BYTE 4000 DUP(0);存储PE文件头内容
ans DWORD 4000 DUP(0);存储答案
ans2 WORD 4000 DUP (0);存储答案 
filebase DWORD ?;保存PE文件头首地址，便于查找NT头

.code
Output PROC count:DWORD
        invoke dw2hex,eax,addr ans;将十六进制数转化成字符串
        CMP count,8h;判断字符串所需位数
        JE P2
        mov ax,word PTR [ans+4];字符串只需要四位的时候输出ans后四位
        mov ans2,ax
        invoke StdOut,addr ans2
        mov ax,word PTR [ans+6]
        mov ans2,ax
        invoke StdOut,addr ans2
        JMP P3

    P2:
        invoke StdOut,addr ans;字符串需要八位的时候直接输出

    P3:
        invoke StdOut,addr endl;回车换行
    ret
Output ENDP
   

start:
    invoke StdOut,addr strf
    invoke StdIn, addr path,4000;输入可执行文件的绝对路径
;打开文件
    invoke CreateFile,addr path,\
                      GENERIC_READ,\
                      FILE_SHARE_READ,\
                      0,\
                      OPEN_EXISTING,\
                      FILE_ATTRIBUTE_ARCHIVE,\
                      0
    mov filehandle,eax;存储文件权柄
    invoke SetFilePointer, filehandle,0,0,FILE_BEGIN
    invoke ReadFile, filehandle,addr filebuf,3900,0,0
    mov esi,OFFSET filebuf;设置文件入口，通过esi偏移输出相应信息

    invoke StdOut,addr str1
    invoke StdOut,addr endl

;e_magic
    mov filebase,esi;保存文件的首地址，便于后续查找NT头
    invoke StdOut,addr str5
    mov ax,word PTR[esi]
    invoke Output,4h

;e_lfanew
    invoke StdOut,addr str6
    ADD esi,3ch
    mov eax,dword PTR[esi]
    invoke Output,8h

invoke StdOut,addr str2
invoke StdOut,addr endl

;Signature
    invoke StdOut,addr str7
    mov eax,dword PTR[esi]
    ADD eax,filebase;将esi移动到NT头
    mov esi,eax
    mov eax,dword PTR[esi]
    invoke Output,8h

invoke StdOut,addr str3
invoke StdOut,addr endl

;NumberOfSections
    invoke StdOut,addr str8
    ADD esi,6h
    mov ax,word PTR[esi]
    invoke Output,4h

;TimeDateStamp
    invoke StdOut,addr str9
    ADD esi,2h
    mov eax,dword PTR[esi]
    invoke Output,8h

;Characteristic
    invoke StdOut,addr stra
    ADD esi,0eh
    mov ax,word PTR[esi]
    invoke Output,4h

invoke StdOut,addr str4
invoke StdOut,addr endl

;AddressOfEntryPoint
    invoke StdOut,addr strb
    ADD esi,12h
    mov eax,dword PTR[esi]
    invoke Output,8h

;ImageBase
    invoke StdOut,addr strc
    ADD esi,0ch
    mov eax,dword PTR[esi]
    invoke Output,8h

;SectionAligment
    invoke StdOut,addr strd
    ADD esi,4h
    mov eax,dword PTR[esi]
    invoke Output,8h

;FileAligment
    invoke StdOut,addr stre
    ADD esi,4h
    mov eax,dword PTR[esi]
    invoke Output,8h

invoke CloseHandle,filehandle;关闭文件
invoke ExitProcess,0

end start
